package com.jixi.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateTime;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jixi.common.exception.PowerFailedException;
import com.jixi.common.result.Result;
import com.jixi.mapper.*;
import com.jixi.pojo.entity.*;
import com.jixi.pojo.vo.SetOrderTodayDownloadVo;
import com.jixi.pojo.vo.SetmealAndOrderInfoVO;
import com.jixi.pojo.vo.SetmealDownLoadVo;
import com.jixi.service.SetmealService;
import jakarta.servlet.http.HttpServletResponse;
import org.burningwave.core.assembler.StaticComponentContainer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
	
	@Autowired
	private SetmealMapper setmealMapper;
	
	@Autowired
	private EducationMapper educationMapper;
	
	@Autowired
	private AuditRecordsMapper auditRecordsMapper;
	
	@Autowired
	private OrderDailyMapper orderDailyMapper;
	
	@Autowired
	private DishMapper dishMapper;
	
	@Autowired
	private SetmealDishMapper setmealDishMapper;
	
	@Autowired
	private CompanyMapper companyMapper;
	
	/**
	 * 导出各套餐统计详细excel
	 */
	@Override
	public void downloadSetmeal(HttpServletResponse response) throws IOException {
		//查询列表
		List<SetmealDownLoadVo> list = setmealMapper.getsetmealDownLoad();
		//excel下载
		StaticComponentContainer.Modules.exportAllToAll();
		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		response.setCharacterEncoding("utf-8");
		String fileName = URLEncoder.encode("各套餐统计详细", "UTF-8").replaceAll("\\+", "%20");
		response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
		EasyExcel.write(response.getOutputStream(), SetmealDownLoadVo.class)
				.sheet("各套餐统计详细")
				.doWrite(list);
	}
	
	/**
	 * 通过套餐id查询套餐信息
	 *
	 * @param setmealId 套餐id
	 * @return 套餐信息
	 */
	@Override
	public Setmeal getSetMealInfoById(Long setmealId) {
		//只查未删除的
		LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(Setmeal::getIsDeleted, 0);
		queryWrapper.eq(Setmeal::getSetmealId, setmealId);
		Setmeal setmeal = setmealMapper.selectOne(queryWrapper);
		return setmeal;
	}
	
	/**
	 * 审核套餐
	 *
	 * @param setmealId      套餐id
	 * @param auditStatus    审核状态
	 * @param examineRemarks 审核备注
	 * @return 审核结果
	 */
	@Override
	public Result updateSetmealExamine(Long setmealId, Integer auditStatus, String examineRemarks) {
		
		//先查登录的账号的权限
		Long loginEducationId = StpUtil.getLoginIdAsLong();
		//构造查询
		LambdaQueryWrapper<Education> queryWrapper = new LambdaQueryWrapper<>();
		//以id作为查询依据
		queryWrapper.eq(Education::getEducationId, loginEducationId);
		//获取实例
		Education loginEducation = educationMapper.selectOne(queryWrapper);
		
		//判断权限
		if (loginEducation.getEducationPower() != 1) {
			throw new PowerFailedException("权限不足");
		}
		
		if (auditStatus != 0 && auditStatus != 1 && auditStatus != 2) {
			return Result.fail("状态值有误");
		}
		/*
		审核记录和套餐的创建由餐饮公司端完成，此处（教育局端）仅作修改。

		对于审核记录来说：status
		0 打回；1 已通过；2 待审核
		每次审核都要改update_time

		对于套餐来说：audit_status
		0 打回；1 审核通过；2 已提交待审核
		审核通过时要改examine_time

		这里的传参（audit_status）是审核记录的状态（status）
		 */
		
		//改审核记录
		LambdaQueryWrapper<AuditRecords> queryWrapperAuditRecords = new LambdaQueryWrapper<>();
		queryWrapperAuditRecords.eq(AuditRecords::getIsDeleted, 0);
		//同一份套餐可能会存在多条审核记录，只查待审核状态的
		queryWrapperAuditRecords.eq(AuditRecords::getStatus, 2);
		queryWrapperAuditRecords.eq(AuditRecords::getSetmealId, setmealId);
		AuditRecords auditRecords = auditRecordsMapper.selectOne(queryWrapperAuditRecords);
		auditRecords.setStatus(auditStatus);
		auditRecords.setAuditRemark(examineRemarks);
		auditRecords.setUpdateTime(DateTime.now());
		auditRecordsMapper.insertOrUpdate(auditRecords);
		
		//改套餐
		LambdaQueryWrapper<Setmeal> queryWrapperSetmeal = new LambdaQueryWrapper<>();
		queryWrapperSetmeal.eq(Setmeal::getIsDeleted, 0);
		queryWrapperSetmeal.eq(Setmeal::getSetmealId, setmealId);
		Setmeal setmeal = setmealMapper.selectOne(queryWrapperSetmeal);
		setmeal.setAuditStatus(auditStatus);
		setmeal.setExamineTime(DateTime.now());
		setmealMapper.insertOrUpdate(setmeal);
		
		return Result.success("审核状态修改成功");
	}
	
	/**
	 * 导出公司与学校相关联的套餐的订单详情excel
	 */
	@Override
	public void downloadCountCompanySchoolSetmeal(HttpServletResponse response, String timeValue) throws IOException {
		//查询列表
		List<SetOrderTodayDownloadVo> list = setmealMapper.getOrderTodayDownLoad(timeValue);
		//excel下载
		StaticComponentContainer.Modules.exportAllToAll();
		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		response.setCharacterEncoding("utf-8");
		String fileName = URLEncoder.encode("日订单明细（" + timeValue + "）", "UTF-8").replaceAll("\\+", "%20");
		response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
		EasyExcel.write(response.getOutputStream(), SetOrderTodayDownloadVo.class)
				.sheet("日订单明细（" + timeValue + "）")
				.doWrite(list);
	}
	
	/**
	 * 套餐条件列表
	 *
	 * @param pageNum     页码
	 * @param pageSize    每页数量
	 * @param setmealName 套餐名称
	 * @param companyId   所属餐饮公司id
	 * @param category    套餐类型
	 * @param auditStatus 审核状态
	 * @param status      状态
	 * @return 套餐列表
	 */
	@Override
	public Result<Page<SetmealAndOrderInfoVO>> setmealPage(
			Integer pageNum,
			Integer pageSize,
			String setmealName,
			Long companyId,
			String category,
			Integer auditStatus,
			Integer status
	) {
		// 分页构造器
		Page<Setmeal> pageInfo = new Page<>(pageNum, pageSize);
		
		// 条件构造器
		LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
		// 只查未删除的
		queryWrapper.eq(Setmeal::getIsDeleted, 0);
		// 添加可能有的过滤条件
		queryWrapper.like(setmealName != null && !setmealName.trim().isEmpty(), Setmeal::getSetmealName, setmealName);
		queryWrapper.eq(companyId != null, Setmeal::getCompanyId, companyId);
		queryWrapper.like(category != null && !category.trim().isEmpty(), Setmeal::getCategory, category);
		queryWrapper.eq(auditStatus != null, Setmeal::getAuditStatus, auditStatus);
		queryWrapper.eq(status != null, Setmeal::getStatus, status);
		//根据更新时间降序排序
		queryWrapper.orderByDesc(Setmeal::getUpdateTime);
		
		// 执行分页查询
		setmealMapper.selectPage(pageInfo, queryWrapper);
		
		// 获取套餐列表
		List<Setmeal> setmealList = pageInfo.getRecords();
		
		// 创建新的套餐列表，包含订单信息
		List<SetmealAndOrderInfoVO> setmealWithOrderInfoList = new ArrayList<>();
		
		//枚举搜索符合的套餐，处理销售量、销售额数据，绑定套餐菜品信息，绑定餐饮公司名字信息
		for (Setmeal setmeal : setmealList) {
			Long setmealId = setmeal.getSetmealId();
			
			// 只查未删除的
			LambdaQueryWrapper<OrderDaily> orderQueryWrapper = new LambdaQueryWrapper<>();
			orderQueryWrapper.eq(OrderDaily::getIsDeleted, 0);
			orderQueryWrapper.eq(OrderDaily::getSetmealId, setmealId);
			// 只查已完成的订单的套餐
			orderQueryWrapper.eq(OrderDaily::getOrderDateStatus, 1);
			
			//处理该订餐的订餐数量与总金额
			Long count = orderDailyMapper.selectCount(orderQueryWrapper);
			Double totalMoney = count * setmeal.getSetmealPrice();
			
			//获取套餐对应的菜品
			//获取中间表
			LambdaQueryWrapper<SetmealDish> setmealDishQueryWrapper = new LambdaQueryWrapper<>();
			setmealDishQueryWrapper.eq(SetmealDish::getIsDeleted, 0);
			setmealDishQueryWrapper.eq(SetmealDish::getSetmealId, setmealId);
			List<SetmealDish> setmealDishList = setmealDishMapper.selectList(setmealDishQueryWrapper);
			//获取菜品
			List<String> dishNameList = new ArrayList<>();
			for(SetmealDish setmealDish : setmealDishList){
				LambdaQueryWrapper<Dish> dishQueryWrapper = new LambdaQueryWrapper<>();
				dishQueryWrapper.eq(Dish::getIsDeleted, 0);
				dishQueryWrapper.eq(Dish::getDishId, setmealDish.getDishId());
				Dish dish = dishMapper.selectOne(dishQueryWrapper);
				if(dish == null){
					dishNameList.add("无菜品信息");
				}
				else {
					dishNameList.add(dish.getDishName());
				}
			}
			
			//处理套餐信息
			SetmealAndOrderInfoVO setmealWithOrderInfo = new SetmealAndOrderInfoVO();
			BeanUtils.copyProperties(setmeal, setmealWithOrderInfo);
			
			//处理餐饮公司名字信息
			Long companyId1 = setmeal.getCompanyId();
			Company company = companyMapper.selectById(companyId1);
			if (company == null || company.getIsDeleted() == 1) {
				setmealWithOrderInfo.setCompanyName("该餐饮公司不存在");
			} else if (company.getStatus() == 0) {
				setmealWithOrderInfo.setCompanyName(company.getCompanyName() + "（该餐饮公司已停用）");
			} else {
				setmealWithOrderInfo.setCompanyName(company.getCompanyName());
			}
			
			//处理其他信息（销售量、销售额、菜品信息）
			setmealWithOrderInfo.setOrderCount(count);
			setmealWithOrderInfo.setTotalMoney(totalMoney);
			setmealWithOrderInfo.setDishes(String.join("，", dishNameList));
			
			setmealWithOrderInfoList.add(setmealWithOrderInfo);
		}
		
		// 创建新的分页对象
		Page<SetmealAndOrderInfoVO> resultPage = new Page<>(pageNum, pageSize);
		resultPage.setRecords(setmealWithOrderInfoList);
		resultPage.setTotal(pageInfo.getTotal());
		resultPage.setSize(pageInfo.getSize());
		resultPage.setCurrent(pageInfo.getCurrent());
		return Result.success(resultPage);
	}
}
